<template>
  <div class="matrix-layout">
    <Panel>
      <PanelItem>
        <div v-if="loading" style="height: 100%">
          <div v-if="columnData.length > 0" class="matrix-layout-table">
            <Grid
              ref="$grid"
              border
              auto-resize
              show-overflow="ellipsis"
              keep-source
              show-header-overflow
              id-property="JE_RBAC_MATRIX_DATA_ID"
              class="select-personnel-grid"
              resizable
              height="100%"
              header-align="center"
              :row-config="{
                keyField: 'JE_RBAC_MATRIX_DATA_ID',
              }"
              :edit-rules="validRules"
              :edit-config="{
                trigger: 'click',
                mode: 'cell',
                showStatus: true,
                showInsertStatus: false,
              }"
              :store="gridStore"
            >
              <GridColumn type="checkbox" width="40" align="center"></GridColumn>
              <GridColumn type="seq" width="60" title="NO." align="center"></GridColumn>
              <GridColumn
                v-for="data in columnData"
                :key="data.field"
                width="200"
                :field="data.field"
                :title="data.title"
                :edit-render="inputRender"
              >
                <template #edit="{ row }">
                  <InputSelectUser
                    v-if="data.dataType == 'user'"
                    v-model:value="row[data.field]"
                    :config-info="getSelectConfig(data, 'user')"
                    placeholder="请选择"
                    :select-options="{
                      title: '选择人员',
                    }"
                  />
                  <InputSelectTree
                    v-else-if="data.dataType == 'department'"
                    v-model:value="row[data.field]"
                    placeholder="请选择"
                    :select-options="{
                      title: '选择部门',
                    }"
                    :config-info="getSelectConfig(data, 'dept')"
                  />
                  <InputSelectTree
                    v-else-if="data.dataType == 'role'"
                    v-model:value="row[data.field]"
                    :model="row"
                    placeholder="请选择"
                    :config-info="getSelectConfig(data, 'role')"
                    :select-options="{
                      title: '选择角色',
                      selectExp: getSelectExp('role'),
                    }"
                  />
                  <Input
                    v-else-if="data.dataType == 'organization'"
                    v-model:value="row[data.field]"
                    placeholder="请输入"
                  />
                  <Input v-else v-model:value="row[data.field]" placeholder="请输入" />
                </template>
              </GridColumn>
              <template #tbar>
                <Toolbar>
                  <Button type="primary" @click="doInsert">
                    <template #icon><i class="jeicon jeicon-plus"></i></template>添加
                  </Button>
                  <Button type="danger" :loading="btnLoading.remove" @click="doRemoveData">
                    <template #icon><i class="jeicon jeicon-times"></i></template>删除
                  </Button>
                  <Button :loading="btnLoading.save" @click="doSaveData">
                    <template #icon><i class="fal fa-save"></i></template> 保存
                  </Button>
                </Toolbar>
              </template>
            </Grid>
          </div>
          <div v-else class="matrix-layout-nodata">
            <div style="width: 100%">
              <img :src="nodata" />
              <p>暂无数据 ~</p>
            </div>
          </div>
        </div>
        <div v-else v-loading="!loading"></div>
      </PanelItem>
    </Panel>
  </div>
</template>

<script>
  import { defineComponent, reactive, ref, watch } from 'vue';
  import { Panel, Grid, Data, Toolbar, Button, Modal, Input, InputSelect } from '@jecloud/ui';
  import { loadData, doUpdateList, doRemove } from '@/api/matrix';
  import { encode, decode, isEmpty } from '@jecloud/utils';
  import { inputRender } from '@/helper/edit-render';
  import { verifyData } from '@/utils/validate';
  import nodata from '@/assets/nodata.png';

  export default defineComponent({
    name: 'MatrixLayout',
    components: {
      Panel,
      PanelItem: Panel.Item,
      Grid,
      GridColumn: Grid.Column,
      Toolbar,
      Button,
      Input,
      InputSelectUser: InputSelect.User,
      InputSelectTree: InputSelect.Tree,
    },
    props: {
      parentId: {
        type: String,
        default: '',
      },
      refreshType: {
        type: Boolean,
        default: false,
      },
    },
    setup(props, { expose }) {
      const dataId = ref('');
      const $grid = ref();
      const loading = ref(false);
      const gridStore = Data.Store.useGridStore({
        idProperty: 'JE_RBAC_MATRIX_DATA_ID',
        data: [],
      });
      const btnLoading = reactive({
        save: false,
        remove: false,
      });
      // 列
      const columnData = ref([]);
      // 全部列字段
      const columnField = ref([]);
      const mainId = ref(props.parentId);
      // 结果字段以及对应的值
      const resultField = ref({});
      const validRules = reactive({});
      // 获得列数据
      const getColumnData = () => {
        loading.value = false;
        columnField.value = [];
        columnData.value = [];
        resultField.value = {};
        dataId.value = '';
        gridStore.loadData([]);
        loadData({
          tableCode: 'JE_RBAC_MATRIX_FIELD',
          funcCode: 'JE_RBAC_MATRIX_FIELD',
          j_query: encode([
            {
              code: 'JE_RBAC_MATRIX_ID',
              type: '=',
              value: mainId.value,
              cn: 'and',
            },
          ]),
        }).then((data) => {
          if (data && data.rows.length > 0) {
            const newColumnField = [];
            data.rows.forEach((item) => {
              columnData.value.push({
                field: item.JE_RBAC_MATRIX_FIELD_ID,
                title: item.FIELD_ZDMC,
                fieldType: item.FIELD_ZDLX_CODE,
                dataType: item.FIELD_SJLX_CODE,
              });
              //组织列的全部字段
              newColumnField.push(item.JE_RBAC_MATRIX_FIELD_ID);
              if (item.FIELD_SJLX_CODE != 'constant') {
                newColumnField.push(item.JE_RBAC_MATRIX_FIELD_ID + '_id');
                newColumnField.push(item.JE_RBAC_MATRIX_FIELD_ID + '_code');
              }
              if (item.FIELD_ZDLX_CODE == 'result') {
                resultField.value[item.JE_RBAC_MATRIX_FIELD_ID + '_type'] = item.FIELD_SJLX_CODE;
              }
            });
            columnField.value = newColumnField;
            //columnData.value == cloneDeep(newColumnData);
            // 添加列表字段校验规则
            loading.value = true;
            addFieldVerify();
            // 加载列表数据
            getGridDate();
          } else {
            loading.value = true;
          }
        });
      };
      // 获得列表数据
      const getGridDate = () => {
        loadData({
          tableCode: 'JE_RBAC_MATRIX_DATA',
          j_query: encode({
            custom: [
              {
                code: 'JE_RBAC_MATRIX_ID',
                type: '=',
                value: mainId.value,
                cn: 'and',
              },
            ],
            order: [{ code: 'SY_CREATETIME', type: 'desc' }],
          }),
        }).then((data) => {
          const girdDatas = [];
          if (data?.rows?.length > 0) {
            data.rows.forEach((item) => {
              const record = decode(item.DATA_JZSJ);
              record.JE_RBAC_MATRIX_DATA_ID = item.JE_RBAC_MATRIX_DATA_ID;
              girdDatas.push(record);
            });
          }
          gridStore.loadData(girdDatas);
        });
      };
      // 添加数据
      const doInsert = () => {
        const row = {};
        columnField.value.forEach((item) => {
          row[item] = '';
        });
        // 添加结果字段类型
        for (let key in resultField.value) {
          row[key] = resultField.value[key];
        }
        gridStore.insert(row);
      };
      // 删除数据
      const doRemoveData = () => {
        const checkboxRecords = $grid.value.getCheckboxRecords();
        if (checkboxRecords.length <= 0) {
          return Modal.alert('请选择要删除的数据！', 'warning');
        }
        Modal.confirm('是否删除数据?', () => {
          btnLoading.remove = false;
          const ids = [];
          checkboxRecords.forEach((item) => {
            ids.push(item.JE_RBAC_MATRIX_DATA_ID);
          });
          doRemove({ tableCode: 'JE_RBAC_MATRIX_DATA', ids: ids.join(',') })
            .then(() => {
              gridStore.remove(checkboxRecords);
              Modal.notice('删除成功！', 'success');
              btnLoading.remove = false;
            })
            .catch(() => {
              btnLoading.remove = false;
            });
        });
      };
      // 保存数据
      const doSaveData = async () => {
        btnLoading.save = true;
        const errMap = await $grid.value.$plugin.validate(gridStore.data);
        if (!errMap) {
          const changes = gridStore.getChanges(true);
          if (isEmpty(changes)) {
            Modal.message('暂无数据变动，无需修改...');
            btnLoading.save = false;
            return false;
          }
          // 参数处理
          const recordData = [];
          changes.forEach((rec) => {
            recordData.push(rec._record);
          });
          const paramsData = [];
          recordData.forEach((item) => {
            const rowParam = { JE_RBAC_MATRIX_DATA_ID: '', DATA_JZSJ: {} };
            for (let key in item) {
              if (key == 'JE_RBAC_MATRIX_DATA_ID' || key == '__action__') {
                rowParam[key] = item[key];
              } else {
                rowParam.DATA_JZSJ[key] = item[key];
              }
            }
            if (item['__action__'] == 'doInsert') {
              rowParam.JE_RBAC_MATRIX_ID = mainId.value;
            }
            rowParam.DATA_JZSJ = encode(rowParam.DATA_JZSJ);
            paramsData.push(rowParam);
          });
          // 保存
          doUpdateList({
            tableCode: 'JE_RBAC_MATRIX_DATA',
            strData: encode(paramsData),
          })
            .then((data) => {
              getGridDate();
              btnLoading.save = false;
              Modal.notice('保存成功！', 'success');
            })
            .catch((e) => {
              btnLoading.save = false;
              Modal.alert(e.message, 'error');
            });
        } else {
          btnLoading.save = false;
        }
      };
      // 获得人员选择器配置
      const getSelectConfig = (item, type) => {
        let config = '';
        if (type == 'user') {
          config = `,${item.field}_code~${item.field}~${item.field}_id,code~text~id,M`;
        } else if (type == 'dept') {
          config = `JE_RBAC_DEPTTREE,${item.field}_code~${item.field}~${item.field}_id,code~text~id,M`;
        } else if (type == 'role') {
          config = `JE_RBAC_ROLETREE,${item.field}_code~${item.field}~${item.field}_id,code~text~id,M`;
        }

        return config;
      };
      // 智能过滤
      const getSelectExp = (type) => {
        let exp = '';
        if (type == 'role') {
          exp = "'{nodeInfoType}' != 'folder'";
        } else if (type == 'dept') {
          exp = "'{nodeInfoType}' != 'company'";
        }
        return exp;
      };
      // 添加列表字段校验规则
      const addFieldVerify = () => {
        columnData.value.forEach((item) => {
          validRules[item.field] = verifyData.required;
        });
      };
      /* watch(
        () => props.parentId,
        (newVal) => {
          if (isNotEmpty(newVal)) {
            mainId.value = newVal;
            getColumnData();
          }
        },
        { immediate: true },
      ); */
      watch(
        () => props.refreshType,
        () => {
          mainId.value = props.parentId;
          getColumnData();
        },
      );
      return {
        gridStore,
        columnData,
        $grid,
        doInsert,
        doRemoveData,
        doSaveData,
        inputRender,
        getSelectConfig,
        getSelectExp,
        validRules,
        btnLoading,
        nodata,
        loading,
      };
    },
  });
</script>

<style lang="less" scoped>
  .matrix-layout {
    height: 100%;
    .matrix-layout-table {
      height: 100%;
      padding: 0 12px;
    }
    .matrix-layout-nodata {
      height: 100%;
      width: 100%;
      text-align: center;
      display: inline-flex;
      align-items: center;
      img {
        display: block;
        margin: 0 auto;
        width: 35%;
      }
      p {
        width: 100%;
        text-align: center;
        font-size: 20px;
        color: #a9aba9;
        padding-top: 20px;
      }
    }
  }
</style>
